<?php

namespace app\admin\controller\booking;

use app\admin\model\User;
use app\admin\model\booking\House;

/**
 *
 */
class Report extends Base
{

    /**
     * 查看
     */
    public function index()
    {
        try {
            \think\Db::execute("SET @@sql_mode='';");
        } catch (\Exception $e) {
        }

        $store_ids = $this->request->post('store_ids', '');
        $house_ids = -1;
        if ($store_ids) {
            $house_ids = House::where('store_id', 'in', $store_ids)->column('id');
        } else {
            $house_ids = -1;
        }


        $authHouseIds = $this->authHouseIds;
        $isSuperAdmin = $this->auth->isSuperAdmin();
        $callback = function ($query) use ($authHouseIds, $isSuperAdmin, $store_ids, $house_ids) {
            if (!$isSuperAdmin) {
                $query->where('source_id', 'in', ($house_ids != -1 ? $house_ids : $authHouseIds));
            } elseif (!empty($store_ids)) {
                $query->where('source_id', 'in', $house_ids);
            }
        };

        //今日订单和会员
        $totalOrderAmount = round(\app\admin\model\booking\Order::where('status', '<>', 'canceled')->where($callback)->where('paytime', '>', 0)->sum('payamount'), 2);
        $yesterdayOrderAmount = round(\app\admin\model\booking\Order::where('status', '<>', 'canceled')->where($callback)->whereTime('paytime', 'yesterday')->sum('payamount'), 2);
        $todayOrderAmount = round(\app\admin\model\booking\Order::where('status', '<>', 'canceled')->where($callback)->whereTime('paytime', 'today')->sum('payamount'), 2);
        $todayOrderRatio = $yesterdayOrderAmount > 0 ? ceil((($todayOrderAmount - $yesterdayOrderAmount) / $yesterdayOrderAmount) * 100) : ($todayOrderAmount > 0 ? 100 : 0);

        if ($this->request->isPost()) {

            $date = $this->request->post('date', '');

            $type = (int)$this->request->post('type', '0');


            switch ($type) {
                case 0:
                    $order_type = $this->request->post('order_type');
                    list($orderSaleCategory, $orderSaleAmount, $orderSaleNums) = $this->getSaleOrderData($date, $house_ids, $order_type);
                    $statistics = [
                        'orderSaleCategory' => $orderSaleCategory,
                        'orderSaleAmount'   => $orderSaleAmount,
                        'orderSaleNums'     => $orderSaleNums,

                        'totalOrderAmount'     => $totalOrderAmount,
                        'todayOrderAmount'     => $todayOrderAmount,
                        'yesterdayOrderAmount' => $yesterdayOrderAmount,
                        'todayOrderRatio'      => $todayOrderRatio,
                    ];
                    $this->success('', '', $statistics);
                    break;
                case 1:
                    //房型占比统计
                    list($legend, $xAxis, $series) = $this->getPercentHouseData($date, $house_ids);
                    $this->success('', '', [
                        'legend' => $legend,
                        'xAxis'  => $xAxis,
                        'series' => $series
                    ]);
                    break;
                case 2:
                    //门店占比统计
                    list($legend, $xAxis, $series) = $this->getPercentStoreData($date, $house_ids);
                    $this->success('', '', [
                        'legend' => $legend,
                        'xAxis'  => $xAxis,
                        'series' => $series
                    ]);
                    break;
            }
        }


        $totalUser = User::count();
        $yesterdayUser = User::whereTime('jointime', 'yesterday')->count();
        $todayUser = User::whereTime('jointime', 'today')->count();
        $todayUserRatio = $yesterdayUser > 0 ? ceil((($todayUser - $yesterdayUser) / $yesterdayUser) * 100) : ($todayUser > 0 ? 100 : 0);


        $this->view->assign("totalOrderAmount", $totalOrderAmount);
        $this->view->assign("yesterdayOrderAmount", $yesterdayOrderAmount);
        $this->view->assign("todayOrderAmount", $todayOrderAmount);
        $this->view->assign("todayOrderRatio", $todayOrderRatio);

        $this->view->assign("totalUser", $totalUser);
        $this->view->assign("yesterdayUser", $yesterdayUser);
        $this->view->assign("todayUser", $todayUser);
        $this->view->assign("todayUserRatio", $todayUserRatio);

        //订单数和订单额统计
        list($orderSaleCategory, $orderSaleAmount, $orderSaleNums) = $this->getSaleOrderData();
        $this->assignconfig('orderSaleCategory', $orderSaleCategory);
        $this->assignconfig('orderSaleAmount', $orderSaleAmount);
        $this->assignconfig('orderSaleNums', $orderSaleNums);


        //房型占比统计
        list($legend, $xAxis, $series) = $this->getPercentHouseData();
        $this->assignconfig('typePercentCategory', $legend);
        $this->assignconfig('typePercentAmount', $xAxis);
        $this->assignconfig('typePercentNums', $series);

        //门店占比统计
        list($storeLegend, $storeXAxis, $storeSeries) = $this->getPercentStoreData();
        $this->assignconfig('storePercentCategory', $storeLegend);
        $this->assignconfig('storePercentAmount', $storeXAxis);
        $this->assignconfig('storePercentNums', $storeSeries);

        return $this->view->fetch();
    }


    /**
     * 获取订单销量销售额统计数据
     */
    protected function getSaleOrderData($date = '', $house_ids = -1, $order_type = '')
    {

        if ($date) {
            list($start, $end) = explode(' - ', $date);
            $starttime = strtotime($start);
            $endtime = strtotime($end);
        } else {
            $starttime = \fast\Date::unixtime('day', 0, 'begin');
            $endtime = \fast\Date::unixtime('day', 0, 'end');
        }
        $totalseconds = $endtime - $starttime;
        $format = '%Y-%m-%d';
        if ($totalseconds > 86400 * 30 * 2) {
            $format = '%Y-%m';
        } else {
            if ($totalseconds > 86400) {
                $format = '%Y-%m-%d';
            } else {
                $format = '%H:00';
            }
        }
        $authHouseIds = $this->authHouseIds;
        $isSuperAdmin = $this->auth->isSuperAdmin();
        $callback = function ($query) use ($authHouseIds, $isSuperAdmin, $house_ids) {
            if (!$isSuperAdmin) {
                $query->where('source_id', 'in', ($house_ids != -1 ? $house_ids : $authHouseIds));
            } elseif ($house_ids != -1) {
                $query->where('source_id', 'in', $house_ids);
            }
        };
        $orderList = \app\admin\model\booking\Order::where('paytime', 'between time', [$starttime, $endtime])
            ->where('status', '<>', 'canceled')
            ->where($callback)
            ->where(function ($query) use ($order_type) {
                if ($order_type != '') {
                    $query->where('type', $order_type);
                }
            })
            ->field('paytime, status, COUNT(*) AS nums, SUM(payamount) AS amount, MIN(paytime) AS min_paytime, MAX(paytime) AS max_paytime, 
            DATE_FORMAT(FROM_UNIXTIME(paytime), "' . $format . '") AS paydate')
            ->group('paydate')
            ->select();

        if ($totalseconds > 84600 * 30 * 2) {
            $starttime = strtotime('last month', $starttime);
            while (($starttime = strtotime('next month', $starttime)) <= $endtime) {
                $column[] = date('Y-m', $starttime);
            }
        } else {
            if ($totalseconds > 86400) {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("Y-m-d", $time);
                    $time += 86400;
                }
            } else {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("H:00", $time);
                    $time += 3600;
                }
            }
        }

        $orderSaleNums = $orderSaleAmount = array_fill_keys($column, 0);
        foreach ($orderList as $k => $v) {
            $orderSaleNums[$v['paydate']] = $v['nums'];
            $orderSaleAmount[$v['paydate']] = round($v['amount'], 2);
        }
        $orderSaleCategory = array_keys($orderSaleAmount);
        $orderSaleAmount = array_values($orderSaleAmount);
        $orderSaleNums = array_values($orderSaleNums);
        return [$orderSaleCategory, $orderSaleAmount, $orderSaleNums];
    }


    /**
     * 获取房间的销售对比
     * //
     */
    protected function getPercentHouseData($date = '', $house_ids = -1)
    {

        if ($date) {
            list($start, $end) = explode(' - ', $date);
            $starttime = strtotime($start);
            $endtime = strtotime($end);
        } else {
            $starttime = \fast\Date::unixtime('day', 0, 'begin');
            $endtime = \fast\Date::unixtime('day', 0, 'end');
        }

        $totalseconds = $endtime - $starttime;
        $format = '%Y-%m-%d';

        if ($totalseconds > 86400 * 30 * 2) {
            $format = '%Y-%m';
        } else {
            if ($totalseconds > 86400) {
                $format = '%Y-%m-%d';
            } else {
                $format = '%H:00';
            }
        }
        $authHouseIds = $this->authHouseIds;
        $isSuperAdmin = $this->auth->isSuperAdmin();
        $callback = function ($query) use ($authHouseIds, $isSuperAdmin, $house_ids) {
            if (!$isSuperAdmin) {
                $query->where('o.source_id', 'in', ($house_ids != -1 ? $house_ids : $authHouseIds));
            } elseif ($house_ids != -1) {
                $query->where('source_id', 'in', $house_ids);
            }
        };
        $orderList = \app\admin\model\booking\Order::where('o.paytime', 'between time', [$starttime, $endtime])
            ->where('o.status', '<>', 'canceled')
            ->where('o.type', 0)
            ->where($callback)
            ->field("count(*) as nums,SUM(o.payamount) AS amount,c.name type_name,FROM_UNIXTIME(o.paytime,'$format') AS paydate")
            ->alias('o')
            ->fetchSql(false)
            ->join('booking_house h', 'h.id=o.source_id', 'LEFT')
            ->join('booking_config c', 'c.id=h.type_config_id', 'LEFT')
            ->order('paytime asc')
            ->group('paydate,type_name')
            ->select();

        $column = [];
        if ($totalseconds > 84600 * 30 * 2) {
            $starttime = strtotime('last month', $starttime);
            while (($starttime = strtotime('next month', $starttime)) <= $endtime) {
                $column[] = date('Y-m', $starttime);
            }
        } else {
            if ($totalseconds > 86400) {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("Y-m-d", $time);
                    $time += 86400;
                }
            } else {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("H:00", $time);
                    $time += 3600;
                }
            }
        }
        $orderSaleNums = array_fill_keys($column, [0, 0]);

        $list = [];
        foreach ($orderList as $item) {
            $list[$item['type_name']][] = $item;
        }

        $series = $legend = [];
        foreach ($list as $key => $item) {
            $legend[] = $key;
            foreach ($item as $res) {
                $orderSaleNums[$res['paydate']] = [$res['nums'], $res['amount']];
            }
            $series[] = [
                'name'      => $key,
                'type'      => 'line',
                'smooth'    => true,
                'areaStyle' => [
                    'normal' => []
                ],
                'lineStyle' => [
                    'normal' => [
                        'width' => 1.5
                    ]
                ],
                'data'      => array_values($orderSaleNums)
            ];
        }
        return [$legend, $column, $series];
    }


    /**
     * 获取门店的销售占比
     */
    protected function getPercentStoreData($date = '', $house_ids = -1)
    {

        if ($date) {
            list($start, $end) = explode(' - ', $date);
            $starttime = strtotime($start);
            $endtime = strtotime($end);
        } else {
            $starttime = \fast\Date::unixtime('day', 0, 'begin');
            $endtime = \fast\Date::unixtime('day', 0, 'end');
        }

        $totalseconds = $endtime - $starttime;
        $format = '%Y-%m-%d';

        if ($totalseconds > 86400 * 30 * 2) {
            $format = '%Y-%m';
        } else {
            if ($totalseconds > 86400) {
                $format = '%Y-%m-%d';
            } else {
                $format = '%H:00';
            }
        }
        $authHouseIds = $this->authHouseIds;
        $isSuperAdmin = $this->auth->isSuperAdmin();
        $callback = function ($query) use ($authHouseIds, $isSuperAdmin, $house_ids) {
            if (!$isSuperAdmin) {
                $query->where('source_id', 'in', ($house_ids != -1 ? $house_ids : $authHouseIds));
            } elseif ($house_ids != -1) {
                $query->where('source_id', 'in', $house_ids);
            }
        };
        $orderList = \app\admin\model\booking\Order::where('o.paytime', 'between time', [$starttime, $endtime])
            ->where('o.status', '<>', 'canceled')
            ->where('o.type', 0)
            ->where($callback)
            ->field("count(*) as nums,s.id store_id,s.name as store_name,SUM(o.payamount) AS amount,FROM_UNIXTIME(o.paytime,'$format') AS paydate")
            ->alias('o')
            ->join('booking_house h', 'h.id=o.source_id')
            ->join('booking_store s', 's.id=h.store_id')
            ->group('s.id,paydate')
            ->select();

        if ($totalseconds > 84600 * 30 * 2) {
            $starttime = strtotime('last month', $starttime);
            while (($starttime = strtotime('next month', $starttime)) <= $endtime) {
                $column[] = date('Y-m', $starttime);
            }
        } else {
            if ($totalseconds > 86400) {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("Y-m-d", $time);
                    $time += 86400;
                }
            } else {
                for ($time = $starttime; $time <= $endtime;) {
                    $column[] = date("H:00", $time);
                    $time += 3600;
                }
            }
        }

        $orderSaleNums = array_fill_keys($column, [0, 0]);

        $list = [];
        foreach ($orderList as $item) {
            $list[$item['store_id']][] = $item;
        }
        $series = $legend = [];
        foreach ($list as $item) {
            $res = [];
            foreach ($item as $ik => $res) {
                if ($ik == 0) {
                    $legend[] = $res['store_name'];
                }
                $orderSaleNums[$res['paydate']] = [$res['nums'], $res['amount']];
            }
            $series[] = [
                'name'      => $res['store_name'] ?? '未知',
                'type'      => 'line',
                'smooth'    => true,
                'areaStyle' => [
                    'normal' => []
                ],
                'lineStyle' => [
                    'normal' => [
                        'width' => 1.5
                    ]
                ],
                'data'      => array_values($orderSaleNums)
            ];
        }
        return [$legend, $column, $series];
    }
}
